
TED chip Music Player - quick docs:
-----------------------------------

	This was a quick port of my old Vic20 player. It's not optimized
or very easy to edit with, but maybe someone will find a use for it, or 
create a better player from it.   It was compiled using the C64ASM cross 
assembler, hopefully it's fairly compatible with other assemblers.

	There are only 2 sound channels on the TED chip but the second 
channel can also be used to play noise.  The pitch table on this chip 
seems to start quite high up, without many bass notes.  You also have a 
global volume control which is shared between both channels instead of 
ADSR commands like on the SID chip.  I've put in a priority system for 
which instruments should be using the volume, but it's a little buggy. :)

Music data limitations:
-----------------------

	Because there isn't much room on the Vic20 I kept the song, pattern
and instrument data to 256 bytes maximum each.  You can have up to 16 
instruments and 16 different patterns in a song.

	An improvement to the player would be to replace the pattern
code & table with 16bit values pointing to seperate labels for each pattern.  
Not only would this make each pattern 256 bytes in length, but the musician 
won't need to recalculate the start position table every time they change 
the data. :)

Tempo:
------

	Tempo is the amount of frames that will pass before the player
continues to the next note, or next duration of that note.  

	After each pass the tempo swaps between two values.  This is so
you can make 'funk tempo' songs or have speeds between the standard settings. 
For example:

	tempo .byte $06,$06 - Play at tempo 6
	tempo .byte $05,$06 - Play at tempo 5.5
	tempo .byte $0a,$06 - Play in a 'funk tempo' style.

Instrument Data:
----------------

	Each instrument has a few bytes to describe it's volume settings and
if it uses the noise channel or has vibrato.  Each vertical column represents
one instrument, for example:

		      Instrument Number
	              0   1   2   3   4
	
	inststr .byte $00,$02,$09,$12,$17
	volstrt .byte $00,$4a,$8e,$8e,$5e
	voldec  .byte $00,$03,$02,$04,$02
	volpri  .byte $00,$03,$05,$04,$05
	notelen .byte $00,$13,$9a,$8a,$88

	volstrt: (Volume Start/Volume End) 
        ---------
	$xy: x = volume to slide to, y = start volume.
	eg: $4a = Start at volume $0a, stop when volume $04 is reached.

	voldec: (Volume slide decay value per frame)
	-------
        eg: $01 = Subtract 1 from the volume every frame until minimum 
	          reached. (not very flexible)

	volpri: (Volume Priority/Vibrato Enabled?)
	-------
	$00-$0f = Volume priority number.
	+$80    = Vibrato enabled on this instrument.

	As there is only one volume control for both channels you can
        set a priority value for each instrument.  The higher the number
        the more likely it is to have control of the volume when
        playing.  This is good for keeping your drums and bass line audible
        if a quiet instrument is also playing.
        eg: $04 = set volume priority to 4 for this instrument.
            $85 = set volume priority to 5 and also have vibrato enabled.
        There are no vibrato settings beyond switching it on or off, it 
        didn't seem worth adding more on the Vic20. (sorry)

	notelen: (Note Length/Noise Channel Enabled?)
	--------
	$00-$7f = Duration (in frames) to play note before silenced.
        +$80    = The instrument will use the noise channel.
        
        Because of the global volume control you'll want your notes to
        stop playing after a time rather than fade the volume to zero. 
        If you add $80 to the note length your instrument will use the
        noise channel. 
        eg: $1f = Play note for $1f frames.
            $9f = Play note for $1f frames and use the noise channel.

	inststr: (Instrument table start position)
	--------
	The byte position that each instrument starts at in the table. 
	eg: .byte $00,$04,$08 = instruments 0,1,2 start at positions 0,4 and 8.

Instrument Table: (insttab) 
-----------------

	Each of the tables (instruments, songdata & patterndata) uses a small 
hex language to describe the contents.  For the instruments each command 
represents one frame of playback time.

	If your instrument is not using the noise channel: 
	-------------------------------------------------- 
	$00     - Play the note in the pattern.
        $01>$df - Play this pitch instead of the note in the pattern & ignore 
                  tranpose.
	$e1-$ef - Transpose note by $1-$f semitones. (Arpeggio)
	$f1-$ff - Loop back $1-$f positions in table. You must have one of 
	          these at the end of each instrument.

	Some example instruments:
	 
	This would make a simple bass drum that returns to the playing note:
	
	position    1   2   3   4
	
   	            $64,$24,$00,$f1 
   	          
   	            1) Play pitch $64
	 	    2) Play pitch $24
 	 	    3) Play the note in the pattern 
 		    4) Loop back to frame 3
 
        And this is a minor chord arpeggio:
        
        position    1   2   3   4   5
          
                    $00,$e3,$e7,$ec,$f4 
                 
                    1) Play note in pattern     
        	    2) Play note transposed by 3 semi-tones
		    3) And by 7 semi-tones
		    4) And now by an octave
		    5) loop back to frame 1 to play the arpeggio again.

	If your instrument uses the noise channel: 
	------------------------------------------
	Each frame of the instrument uses two bytes instead of one.  The first 
	byte uses the same commands as above, but the second byte is the pitch 
	to play on the noise channel in the range $01-$ff.

	You can use combinations of pulse & noise values in a single 
	instrument, if the noise value for that frame is set to zero then the 
	pulse value will be used, whereas if the noise value is greater than
	zero the pulse value will be ignored and the noise will play.
	
        For the loop command you still only need to count 1 byte steps, the player 
        will treat them as two.
	
        Some example instruments, remember to count two bytes for each frame:

	This plays a bass drum with a hihat at the start that returns to the 
	playing pulse note: 
	
	position   1       2       3       4       5
	  
	           $00,$fd,$07,$00,$00,$14,$00,$00,$f1 
	
                   1) Play pitch $fd on noise channel
		   2) Play pitch $07 on pulse channel
		   3) Play pitch $14 on noise channel
		   4) Play note from pattern on pulse channel
		   5) Loop back to position 4 (you only need 
		      1 byte for the loop command)

	This plays a snare sound using combination of pulse & noise channels:
	
	position   1       2       3       4       5
	  
                   $05,$00,$c5,$00,$00,$d0,$00,$e4,$f3
        
                   1) Play pitch $05 on pulse channel
		   2) Play pitch $c5 on pulse channel
		   3) Play pitch $d0 on noise channel
		   4) Play pitch $e4 on noise channel
		   5) Loop back to position 2

Pattern Table: (patttab)
--------------

	This is where your music data is stored.  As with the instruments 
there is an offset table describing where each pattern starts, called 
'pattstart'. eg: byte $00,$0a,$14 = patterns 0,1,2 start at $00,$0a & $14
in the patttab table.

        The pattern data has four commands:

	$00-$3f = Play this note from the frequency table. (0 = silence)

		The frequency table is as follows:
	
		note | c  c#  d   d#   e   f  f#  g   g#  a   a#   b	      
	 octave -----+-----------------------------------------------
		0    | 1  2   3   4    5   6  7   8   9   a   b    c
	 	1    | d  e   f   10   11  12 13  14  15  16  17   18
		2    | 19 1a  1b  1c   1d  1e 1f  20  21  22  23   24
		3    | 25 26  27  28   29  2a 2b  2c  2d  2e  2f   30
		4    | 31 32  33  34   35  36 37  38  39  3a  3b   3c
        	5    | 3d 3e  3f  

	$80-$8f = Set duration of following notes to $01-$10.  This is how
                  many passes of the tempo count will happen before the next
                  note is played, so larger values = larger duration.

		  eg : If tempo = 6 then $80 = 1*6 = play for 6 frames.
		                         $83 = 4*6 = play for 24 frames.
					 $8f = 16*6 = play for 96 frames.
		  The duration value is used for that channel until another 
		  duration is set, so remember to reset it at the start of 
		  your song. :)
		  
	$f0-$ff = Change the instrument used for the following notes to 
	          instrument $0-$f.

	          eg : $f0 = Play instrument 0, $f7 = Play instrument 7.  

		  The instrument is used for that channel until another 
		  instrument change is reached.
		  
	By default when a song begins the instrument and duration are both set
	to zero for both channels.
		  
	$7f     = End Pattern marker.  You must have one of these at the end
	          of the pattern.

	An example pattern:

        position   1   2   3   4   5   6   7   8   9  10
   
	           $80,$f4,$03,$05,$81,$06,$f7,$16,$20,$7f 

	           1) Set duration to 0 (1*tempo) 
	           2) Set instrument to 4
	 	   3) Play note $03 (d, octave 0)
		   4) Play note $05 (e, octave 0)
		   5) Set duration to 1 (2*tempo)
		   6) Play note $06 (f, octave 0)
		   7) Set instrument to 7
		   8) Play note $16 (a, octave 1)
		   9) Play note $20 (g, octave 2)
		  10) End pattern

Song Table: (songtab)
-----------

	This is where a sequence of patterns is put together to form a song.  
You can repeat patterns, loop back to save memory and also tranpose them.  As 
with the other tables there is an offset table (songstr) which must contain 
the start positions for the two channels.
 
	Songdata has four commands:

	$xy     = x is Transpose value of $0-$d semitones, and y = Pattern number.
	          eg : $07 = play pattern 7 with no tranpose.
	               $35 = play pattern 5 with a tranpose of 3 semitones.
		   
	$e1-$ef = jump back $1-$f places and play the previous song data again from
	          that point.  The next time this command is reached it will be ignored
	          until the song loops back to the beginning.
	          eg : $01,$02,$03,$e2 = go back two bytes and play $02,$03 again.

	$f1-$fe = repeat the next pattern $2-$f amount of times. (add +1 to repeat value) 
		  eg : $f3,$05 = play pattern 5 for 4 times.

	$ff    	= End of songdata for this channel.  You must have this at the end of
	          each channel's songdata.

        An example song channel:

        position  1   2   3   4   5   6   7
          
                  $03,$73,$f3,$02,$e4,$05,$ff 
        
                  1) Play pattern 3 with no transpose.
                  2) Play pattern 3 with transpose of +7.
                3+4) Repeat pattern 2 for 4 times.
                  5) Go back 4 places and play positions 1-4 again.
                  6) Play pattern 5 with no transpose.
                  7) End songdata for this channel.
                                      
Final notes:
------------

	I hope these instructions are fairly easy to understand, but there may be 
something I've forgotten or some bugs in the player.  Apologies for that, I
haven't used this sound system since 2004. :)
